proc sendmsg {} {
	set msg [.inputfr.input get]
	
	global n_conns
	global conns
	global mes
	global UHOSTS
	global FILES
	
	set chid [getchid]
	global CHANS_$chid
	
	set currservertab $n_conns.$chid
	set channel [$currservertab tab [$currservertab select] -text]	
	set view [getchan]
	set me $mes($chid)
	set tstamp [clock format [clock seconds] -format "%T"]
	
	puts [regexp {/(.+)} $msg]
	if [regexp {/(.+)} $msg -> cmd] {
		switch -- [string tolower [lindex [split $cmd] 0]] {
			join - j {
				if {"[lindex $cmd 1]" == ""} {
					errmsg $view "[tr Usage]: /[lindex [split $cmd] 0] <channel-list>\n"
					return
				}

				set chan "[lrange $cmd 1 end]"
				if [regexp {\{([^\}]+)\}} $chan -> n_chan] {
					set chan $n_chan
					unset n_chan
				}
				
				foreach channel [string map {"," " "} $chan] {
					raw $chid "JOIN $channel"
				}
			}
			
			part {
				if {"[lindex $cmd 1]" == ""} {
					errmsg $view "[tr Usage]: /part <channel>\n"
					return
				}
				
				raw $chid "PART [lindex $cmd 1]"
			}
			
			me {
				if {"[lindex $cmd 1]" == ""} {
					errmsg $view "[tr Usage]: /me <message>\n"
					return
				}
				
				raw $chid "PRIVMSG $channel :\001ACTION [lrange $cmd 1 end]\001"
				output $view "* $me [lrange $cmd 1 end]\n" purple
				$view.mainbox.output yview end
			}
			
			notice {
				if {"[lindex $cmd 2]" == ""} {
					errmsg $view "[tr Usage]: /notice <target> <message>\n"
					return
				}
				set n [lindex $cmd 1]
				raw $chid "NOTICE $n :[lrange $cmd 2 end]"
				output $currservertab.console "\[$tstamp\] \[NOTICE > $n\] [lrange $cmd 2 end]\n"
			}
			
			quit {
				raw $chid "QUIT :[lrange $cmd 1 end]"
				close $chid
				$n_conns forget $currservertab
				destroy $currservertab
			}
			
			mode {
				if { "[lindex $cmd 2]" == ""} {
					errmsg $view "[tr Usage]: /mode <target> <modestring>\n"
					return
				}
				
				raw $chid "MODE [lrange $cmd 1 end]"
			}
			
			kick {
				if {"[lindex $cmd 1]" == ""} {
					errmsg $view "[tr Usage]: /kick <nick> \[reason\]\n"
					return
				}
				
				if [regexp {([^ ]+) ([^ ]+)(.*)} [lrange $cmd 1 end] -> \
					channel victim reason] {
					if { "$reason" == "" } { set reason $me; }
					raw $chid "KICK $channel $victim :$reason"
				}
			}
			
			nick {
				if {"[lindex $cmd 1]" == ""} {
					errmsg $view "[tr Usage]: /nick <newnick>\n"
					return
				}
				raw $chid "NICK [lindex $cmd 1 end]"
			}
			
			msg {
				if {"[lindex $cmd 2]" == ""} {
					errmsg $view "[tr Usage]: /msg <target> <message>\n"
					return
				}
				set n [lindex $cmd 1]
				raw $chid "PRIVMSG $n :[lrange $cmd 2 end]"
				output $currservertab.console "\[$tstamp\] \[PRIVMSG > $n\] [lrange $cmd 2 end]\n"
			}
			
			ctcp {
				if {"[lindex $cmd 2]" == ""} {
					errmsg $view "[tr Usage]: /ctcp <nick> <what>\n"
					return
				}
				set n [lindex $cmd 1]
				set msg [lrange $cmd 2 end]
				raw $chid "PRIVMSG $n :\001$msg\001"
			}
			
			whois {
				if {"[lindex $cmd 1]" == ""} {
					errmsg $view "[tr Usage]: /whois <nick>\n"
					return
				}
				set n [lindex $cmd 1]
				raw $chid "WHOIS $n"
			}
			
			userhost {
				set nick [lindex $cmd 1]
				set uhost $UHOSTS($nick)
				output $view "$nick is $uhost"
			}
			
			kb - kickban {
				if {"[lindex $cmd 1 end]" == ""} {
					errmsg $view "[tr Usage]: /[lindex $cmd 0] <nick> \[reason\]\n"
					return
				}
				set victim [lindex $cmd 1]
				set reason [lrange $cmd 2 end]
				
				if {$reason == ""} {
					set reason $me
				}
				
				set uhost $UHOSTS($victim)
				set mask [maskhost "$victim!$uhost"]
				raw $chid "MODE $channel +b $mask"
				raw $chid "KICK $channel $victim :$reason"
			}
			
			host - dns {
				if {[llength $cmd] != 2} {
					errmsg $view "[tr Usage]: /[lindex $cmd 0] <host/ip>"
					return 1
				}
				
				output $view "[tr Resolving] [lindex $cmd 1]...\n"
				dns::resolve "[lindex $cmd 1]" -command dnscallback
			}
			
			reload {
				foreach file $FILES {
				source [file join $starkit::topdir $file.tcl]
				}
			}
			
			raw {
				raw $chid "[lrange $cmd 1 end]"
			}
			
			default {
				raw $chid "[lrange $cmd 0 end]"
			}
		}
	} else {
		set currservertab $n_conns.$chid
		set channel [$currservertab tab [$currservertab select] -text]
		
		raw $chid "PRIVMSG $channel :$msg"
		$view.mainbox.output insert end "\[$tstamp\] <"
		$view.mainbox.output insert end "$me" {bold blue}
		$view.mainbox.output insert end "> $msg\n"
		$view.mainbox.output yview end
	}
	
	.inputfr.input delete 0 end
}

bind .inputfr.input <Return> sendmsg
bind .inputfr.input <Prior> {scrolloutput -4}
bind .inputfr.input <Next> {scrolloutput +4}
bind . <Menu> {.mb activate 0}
